1   /*                        __    __  __  __    __  ___
2    *                       \  \  /  /    \  \  /  /  __/
3    *                        \  \/  /  /\  \  \/  /  /
4    *                         \____/__/  \__\____/__/.ɪᴏ
5    * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
6    */
7   package io.vavr;
8   
9   import io.vavr.collection.*;
10  import io.vavr.control.Either;
11  import io.vavr.control.Try;
12  import io.vavr.control.Validation;
13  import io.vavr.collection.Array;
14  import io.vavr.collection.CharSeq;
15  import io.vavr.collection.Stream;
16  import io.vavr.concurrent.Future;
17  import io.vavr.control.Option;
18  import org.assertj.core.api.*;
19  import org.junit.Test;
20  
21  import java.io.Serializable;
22  import java.util.*;
23  import java.util.Collections;
24  import java.util.function.Function;
25  import java.util.function.Supplier;
26  
27  import static io.vavr.API.*;
28  import static io.vavr.Predicates.anyOf;
29  import static io.vavr.Predicates.instanceOf;
30  
31  public abstract class AbstractValueTest {
32  
33      protected Random getRandom(int seed) {
34          if (seed >= 0) {
35              return new Random(seed);
36          } else {
37              final Random random = new Random();
38              seed = random.nextInt();
39              System.out.println("using seed: " + seed);
40              random.setSeed(seed);
41              return random;
42          }
43      }
44  
45      protected <T> IterableAssert<T> assertThat(Iterable<T> actual) {
46          return new IterableAssert<T>(actual) {};
47      }
48  
49      protected <T> ObjectAssert<T> assertThat(T actual) {
50          return new ObjectAssert<T>(actual) {};
51      }
52  
53      protected <T> ObjectArrayAssert<T> assertThat(T[] actual) {
54          return new ObjectArrayAssert<T>(actual) {};
55      }
56  
57      protected BooleanAssert assertThat(Boolean actual) {
58          return new BooleanAssert(actual) {};
59      }
60  
61      protected DoubleAssert assertThat(Double actual) {
62          return new DoubleAssert(actual) {};
63      }
64  
65      protected IntegerAssert assertThat(Integer actual) {
66          return new IntegerAssert(actual) {};
67      }
68  
69      protected LongAssert assertThat(Long actual) {
70          return new LongAssert(actual) {};
71      }
72  
73      protected StringAssert assertThat(String actual) {
74          return new StringAssert(actual) {};
75      }
76  
77      abstract protected <T> Value<T> empty();
78  
79      abstract protected <T> Value<T> of(T element);
80  
81      @SuppressWarnings("unchecked")
82      abstract protected <T> Value<T> of(T... elements);
83  
84      // TODO: Eliminate this method. Switching the behavior of unit tests is evil. Tests should not contain additional logic. Also it seems currently to be used in different sematic contexts.
85      abstract protected boolean useIsEqualToInsteadOfIsSameAs();
86  
87      // returns the peek result of the specific Traversable implementation
88      abstract protected int getPeekNonNilPerformingAnAction();
89  
90      // -- get()
91  
92      @Test(expected = NoSuchElementException.class)
93      public void shouldGetEmpty() {
94          empty().get();
95      }
96  
97      @Test
98      public void shouldGetNonEmpty() {
99          assertThat(of(1).get()).isEqualTo(1);
100     }
101     
102     // -- getOrElse(T)
103 
104     @Test
105     public void shouldCalculateGetOrElseWithNull() {
106         assertThat(this.<Integer> empty().getOrElse((Integer) null)).isEqualTo(null);
107         assertThat(of(1).getOrElse((Integer) null)).isEqualTo(1);
108     }
109 
110     @Test
111     public void shouldCalculateGetOrElseWithNonNull() {
112         assertThat(empty().getOrElse(1)).isEqualTo(1);
113         assertThat(of(1).getOrElse(2)).isEqualTo(1);
114     }
115 
116     // -- getOrElse(Supplier)
117 
118     @Test(expected = NullPointerException.class)
119     public void shouldThrowOnGetOrElseWithNullSupplier() {
120         final Supplier<?> supplier = null;
121         empty().getOrElse(supplier);
122     }
123 
124     @Test
125     public void shouldCalculateGetOrElseWithSupplier() {
126         assertThat(empty().getOrElse(() -> 1)).isEqualTo(1);
127         assertThat(of(1).getOrElse(() -> 2)).isEqualTo(1);
128     }
129 
130     // -- getOrElseThrow
131 
132     @Test(expected = ArithmeticException.class)
133     public void shouldThrowOnGetOrElseThrowIfEmpty() {
134         empty().getOrElseThrow(ArithmeticException::new);
135     }
136 
137     @Test
138     public void shouldNotThrowOnGetOrElseThrowIfNonEmpty() {
139         assertThat(of(1).getOrElseThrow(ArithmeticException::new)).isEqualTo(1);
140     }
141 
142     // -- getOrElseTry
143 
144     @Test
145     public void shouldReturnUnderlyingValueWhenCallingGetOrElseTryOnNonEmptyValue() {
146         assertThat(of(1).getOrElseTry(() -> 2)).isEqualTo(1);
147     }
148 
149     @Test
150     public void shouldReturnAlternateValueWhenCallingGetOrElseTryOnEmptyValue() {
151         assertThat(empty().getOrElseTry(() -> 2)).isEqualTo(2);
152     }
153 
154     @Test(expected = Error.class)
155     public void shouldThrowWhenCallingGetOrElseTryOnEmptyValueAndTryIsAFailure() {
156         empty().getOrElseTry(() -> {
157             throw new Error();
158         });
159     }
160 
161     // -- getOrNull
162 
163     @Test
164     public void shouldReturnNullWhenGetOrNullOfEmpty() {
165         assertThat(empty().getOrNull()).isEqualTo(null);
166     }
167 
168     @Test
169     public void shouldReturnValueWhenGetOrNullOfNonEmpty() {
170         assertThat(of(1).getOrNull()).isEqualTo(1);
171     }
172 
173     // -- forEach
174 
175     @Test
176     public void shouldPerformsActionOnEachElement() {
177         final int[] consumer = new int[1];
178         final Value<Integer> value = of(1, 2, 3);
179         value.forEach(i -> consumer[0] += i);
180         assertThat(consumer[0]).isEqualTo(value.isSingleValued() ? 1 : 6);
181     }
182 
183     // -- isAsync
184 
185     @Test
186     public void shouldVerifyAsyncProperty() {
187         assertThat(empty().isAsync()).isFalse();
188         assertThat(of(1).isAsync()).isFalse();
189     }
190 
191     // -- isEmpty
192 
193     @Test
194     public void shouldCalculateIsEmpty() {
195         assertThat(empty().isEmpty()).isTrue();
196         assertThat(of(1).isEmpty()).isFalse();
197     }
198 
199     // -- isLazy
200 
201     @Test
202     public void shouldVerifyLazyProperty() {
203         assertThat(empty().isLazy()).isFalse();
204         assertThat(of(1).isLazy()).isFalse();
205     }
206 
207     // -- peek
208 
209     @Test
210     public void shouldPeekNil() {
211         assertThat(empty().peek(t -> {})).isEqualTo(empty());
212     }
213 
214     @Test
215     public void shouldPeekNonNilPerformingNoAction() {
216         assertThat(of(1).peek(t -> {})).isEqualTo(of(1));
217     }
218 
219     @Test
220     public void shouldPeekSingleValuePerformingAnAction() {
221         final int[] effect = { 0 };
222         final Value<Integer> actual = of(1).peek(i -> effect[0] = i);
223         assertThat(actual).isEqualTo(of(1));
224         assertThat(effect[0]).isEqualTo(1);
225     }
226 
227     @Test
228     public void shouldPeekNonNilPerformingAnAction() {
229         final int[] effect = { 0 };
230         final Value<Integer> actual = of(1, 2, 3).peek(i -> effect[0] = i);
231         assertThat(actual).isEqualTo(of(1, 2, 3)); // traverses all elements in the lazy case
232         assertThat(effect[0]).isEqualTo(getPeekNonNilPerformingAnAction());
233     }
234 
235     // -- Conversions toXxx()
236 
237     @Test
238     public void shouldConvertToArray() {
239         final Value<Integer> value = of(1, 2, 3);
240         final Array<Integer> array = value.toArray();
241         if (value.isSingleValued()) {
242             assertThat(array).isEqualTo(Array.of(1));
243         } else {
244             assertThat(array).isEqualTo(Array.of(1, 2, 3));
245         }
246     }
247 
248     @Test
249     public void shouldConvertToCharSeq() {
250         final Value<Integer> value = of(1, 2, 3);
251         final CharSeq charSeq = value.toCharSeq();
252         final CharSeq expected = CharSeq.of(of(1, 2, 3).iterator().mkString());
253         assertThat(charSeq).isEqualTo(expected);
254     }
255 
256     @Test
257     public void shouldConvertToList() {
258         final Value<Integer> value = of(1, 2, 3);
259         final io.vavr.collection.List<Integer> list = value.toList();
260         if (value.isSingleValued()) {
261             assertThat(list).isEqualTo(io.vavr.collection.List.of(1));
262         } else {
263             assertThat(list).isEqualTo(io.vavr.collection.List.of(1, 2, 3));
264         }
265     }
266 
267     @Test
268     public void shouldConvertToHashMap() {
269         final Value<Integer> value = of(9, 5, 1);
270         final io.vavr.collection.Map<Integer, Integer> map = value.toMap(i -> Tuple.of(i, i));
271         if (value.isSingleValued()) {
272             assertThat(map).isEqualTo(io.vavr.collection.HashMap.of(9, 9));
273         } else {
274             assertThat(map).isEqualTo(io.vavr.collection.HashMap.of(1, 1, 5, 5, 9, 9));
275         }
276     }
277 
278     @Test
279     public void shouldConvertToHashMapTwoFunctions() {
280         final Value<Integer> value = of(9, 5, 1);
281         final io.vavr.collection.Map<Integer, Integer> map = value.toMap(Function.identity(), Function.identity());
282         if (value.isSingleValued()) {
283             assertThat(map).isEqualTo(io.vavr.collection.HashMap.of(9, 9));
284         } else {
285             assertThat(map).isEqualTo(io.vavr.collection.HashMap.of(1, 1, 5, 5, 9, 9));
286         }
287     }
288 
289     @Test
290     public void shouldConvertToLinkedMap() {
291         final Value<Integer> value = of(1, 5, 9);
292         final io.vavr.collection.Map<Integer, Integer> map = value.toLinkedMap(i -> Tuple.of(i, i));
293         if (value.isSingleValued()) {
294             assertThat(map).isEqualTo(io.vavr.collection.LinkedHashMap.of(1, 1));
295         } else {
296             assertThat(map).isEqualTo(io.vavr.collection.LinkedHashMap.of(1, 1, 5, 5, 9, 9));
297         }
298     }
299 
300     @Test
301     public void shouldConvertToLinkedMapTwoFunctions() {
302         final Value<Integer> value = of(1, 5, 9);
303         final io.vavr.collection.Map<Integer, Integer> map = value.toLinkedMap(Function.identity(), Function.identity());
304         if (value.isSingleValued()) {
305             assertThat(map).isEqualTo(io.vavr.collection.LinkedHashMap.of(1, 1));
306         } else {
307             assertThat(map).isEqualTo(io.vavr.collection.LinkedHashMap.of(1, 1, 5, 5, 9, 9));
308         }
309     }
310 
311     @Test
312     public void shouldConvertToSortedMap() {
313         final Value<Integer> value = of(9, 5, 1);
314         final io.vavr.collection.SortedMap<Integer, Integer> map = value.toSortedMap(i -> Tuple.of(i, i));
315         if (value.isSingleValued()) {
316             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(9, 9));
317         } else {
318             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(1, 1, 5, 5, 9, 9));
319         }
320     }
321 
322     @Test
323     public void shouldConvertToSortedMapTwoFunctions() {
324         final Value<Integer> value = of(9, 5, 1);
325         final io.vavr.collection.SortedMap<Integer, Integer> map = value.toSortedMap(Function.identity(), Function.identity());
326         if (value.isSingleValued()) {
327             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(9, 9));
328         } else {
329             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(1, 1, 5, 5, 9, 9));
330         }
331     }
332 
333     @Test
334     public void shouldConvertToSortedMapWithComparator() {
335         final Value<Integer> value = of(9, 5, 1);
336         final Comparator<Integer> comparator = ((Comparator<Integer>) Integer::compareTo).reversed();
337         final io.vavr.collection.SortedMap<Integer, Integer> map = value.toSortedMap(comparator, i -> Tuple.of(i, i));
338         if (value.isSingleValued()) {
339             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(comparator, 9, 9));
340         } else {
341             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(comparator, 9, 9, 5, 5, 1, 1));
342         }
343     }
344 
345     @Test
346     public void shouldConvertToSortedMapTwoFunctionsWithComparator() {
347         final Value<Integer> value = of(9, 5, 1);
348         final Comparator<Integer> comparator = ((Comparator<Integer>) Integer::compareTo).reversed();
349         final io.vavr.collection.SortedMap<Integer, Integer> map = value.toSortedMap(comparator, Function.identity(), Function.identity());
350         if (value.isSingleValued()) {
351             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(comparator, 9, 9));
352         } else {
353             assertThat(map).isEqualTo(io.vavr.collection.TreeMap.of(comparator, 9, 9, 5, 5, 1, 1));
354         }
355     }
356 
357     @Test
358     public void shouldConvertToOption() {
359         assertThat(empty().toOption()).isSameAs(Option.none());
360         assertThat(of(1).toOption()).isEqualTo(Option.of(1));
361     }
362 
363     @Test
364     public void shouldConvertToEither() {
365         assertThat(empty().toEither("test")).isEqualTo(Left("test"));
366         assertThat(empty().toEither(() -> "test")).isEqualTo(Left("test"));
367         assertThat(of(1).toEither("test")).isEqualTo(Right(1));
368     }
369 
370     @Test
371     public void shouldConvertToValidation() {
372         assertThat(empty().toValidation("test")).isEqualTo(Invalid("test"));
373         assertThat(empty().toValidation(() -> "test")).isEqualTo(Invalid("test"));
374         assertThat(of(1).toValidation("test")).isEqualTo(Valid(1));
375     }
376 
377     @Test
378     public void shouldConvertToQueue() {
379         final Value<Integer> value = of(1, 2, 3);
380         final io.vavr.collection.Queue<Integer> queue = value.toQueue();
381         if (value.isSingleValued()) {
382             assertThat(queue).isEqualTo(io.vavr.collection.Queue.of(1));
383         } else {
384             assertThat(queue).isEqualTo(io.vavr.collection.Queue.of(1, 2, 3));
385         }
386     }
387 
388     @Test
389     public void shouldConvertToPriorityQueueUsingImplicitComparator() {
390         final Value<Integer> value = of(1, 3, 2);
391         final io.vavr.collection.PriorityQueue<Integer> queue = value.toPriorityQueue();
392         if (value.isSingleValued()) {
393             assertThat(queue).isEqualTo(io.vavr.collection.PriorityQueue.of(1));
394         } else {
395             assertThat(queue).isEqualTo(io.vavr.collection.PriorityQueue.of(1, 2, 3));
396         }
397     }
398 
399     @Test
400     public void shouldConvertToPriorityQueueUsingExplicitComparator() {
401         final Comparator<Integer> comparator = Comparator.naturalOrder();
402         final Value<Integer> value = of(1, 3, 2);
403         final io.vavr.collection.PriorityQueue<Integer> queue = value.toPriorityQueue(comparator);
404         if (value.isSingleValued()) {
405             assertThat(queue).isEqualTo(io.vavr.collection.PriorityQueue.of(comparator, 1));
406         } else {
407             assertThat(queue).isEqualTo(io.vavr.collection.PriorityQueue.of(comparator, 1, 2, 3));
408         }
409     }
410 
411     @Test
412     public void shouldConvertToPriorityQueueUsingSerializableComparator() {
413         final Value<Integer> value = of(1, 3, 2);
414         final io.vavr.collection.PriorityQueue<Integer> queue = value.toPriorityQueue();
415         final io.vavr.collection.PriorityQueue<Integer> actual = Serializables.deserialize(Serializables.serialize(queue));
416         assertThat(actual).isEqualTo(queue);
417     }
418 
419     @Test
420     public void shouldConvertToSet() {
421         final Value<Integer> value = of(1, 2, 3);
422         final io.vavr.collection.Set<Integer> set = value.toSet();
423         if (value.isSingleValued()) {
424             assertThat(set).isEqualTo(io.vavr.collection.HashSet.of(1));
425         } else {
426             assertThat(set).isEqualTo(io.vavr.collection.HashSet.of(1, 2, 3));
427         }
428     }
429 
430     @Test
431     public void shouldConvertToLinkedSet() {
432         final Value<Integer> value = of(3, 7, 1, 15, 0);
433         final io.vavr.collection.Set<Integer> set = value.toLinkedSet();
434         if (value.isSingleValued()) {
435             assertThat(set).isEqualTo(io.vavr.collection.LinkedHashSet.of(3));
436         } else {
437             final io.vavr.collection.List<Integer> itemsInOrder;
438             if (value instanceof Traversable && !((Traversable) value).isTraversableAgain()) {
439                 itemsInOrder = io.vavr.collection.List.of(3, 7, 1, 15, 0);
440             } else {
441                 itemsInOrder = value.toList();
442             }
443             assertThat(set).isEqualTo(itemsInOrder.foldLeft(io.vavr.collection.LinkedHashSet.empty(), io.vavr.collection.LinkedHashSet::add));
444         }
445     }
446 
447     @Test
448     public void shouldConvertToSortedSetWithoutComparatorOnComparable() {
449         final Value<Integer> value = of(3, 7, 1, 15, 0);
450         final io.vavr.collection.SortedSet<Integer> set = value.toSortedSet();
451         if (value.isSingleValued()) {
452             assertThat(set).isEqualTo(io.vavr.collection.TreeSet.of(3));
453         } else {
454             assertThat(set).isEqualTo(io.vavr.collection.TreeSet.of(0, 1, 3, 7, 15));
455         }
456     }
457 
458     @Test(expected = ClassCastException.class)
459     public void shouldThrowOnConvertToSortedSetWithoutComparatorOnNonComparable() {
460         final Value<StringBuilder> value = of(new StringBuilder("3"), new StringBuilder("7"), new StringBuilder("1"), new StringBuilder("15"), new StringBuilder("0"));
461         final io.vavr.collection.SortedSet<StringBuilder> set = value.toSortedSet();
462         if (value.isSingleValued()) {
463             //Comparator is not used yet
464             set.add(new StringBuilder("7"));
465         }
466     }
467 
468     @Test
469     public void shouldConvertToSortedSet() {
470         final Value<Integer> value = of(3, 7, 1, 15, 0);
471         final Comparator<Integer> comparator = Comparator.comparingInt(Integer::bitCount);
472         final io.vavr.collection.SortedSet<Integer> set = value.toSortedSet(comparator.reversed());
473         if (value.isSingleValued()) {
474             assertThat(set).isEqualTo(io.vavr.collection.TreeSet.of(3));
475         } else {
476             assertThat(set).isEqualTo(io.vavr.collection.TreeSet.of(comparator.reversed(), 0, 1, 3, 7, 15));
477         }
478     }
479 
480     @Test
481     public void shouldConvertToSortedSetUsingSerializableComparator() {
482         final Value<Integer> value = of(1, 3, 2);
483         final io.vavr.collection.SortedSet<Integer> set = value.toSortedSet();
484         final io.vavr.collection.SortedSet<Integer> actual = Serializables.deserialize(Serializables.serialize(set));
485         assertThat(actual).isEqualTo(set);
486     }
487 
488     @Test
489     public void shouldConvertToStream() {
490         final Value<Integer> value = of(1, 2, 3);
491         final Stream<Integer> stream = value.toStream();
492         if (value.isSingleValued()) {
493             assertThat(stream).isEqualTo(Stream.of(1));
494         } else {
495             assertThat(stream).isEqualTo(Stream.of(1, 2, 3));
496         }
497     }
498 
499     @Test
500     public void shouldConvertNonEmptyToTry() {
501         assertThat(of(1, 2, 3).toTry()).isEqualTo(Try.of(() -> 1));
502     }
503 
504     @Test
505     public void shouldConvertEmptyToTry() {
506         final Try<?> actual = empty().toTry();
507         assertThat(actual.isFailure()).isTrue();
508         assertThat(actual.getCause()).isInstanceOf(NoSuchElementException.class);
509     }
510 
511     @Test
512     public void shouldConvertNonEmptyToTryUsingExceptionSupplier() {
513         final Exception x = new Exception("test");
514         assertThat(of(1, 2, 3).toTry(() -> x)).isEqualTo(Try.of(() -> 1));
515     }
516 
517     @Test
518     public void shouldConvertEmptyToTryUsingExceptionSupplier() {
519         final Exception x = new Exception("test");
520         assertThat(empty().toTry(() -> x)).isEqualTo(Try.failure(x));
521     }
522 
523     @Test
524     public void shouldConvertToVector() {
525         final Value<Integer> value = of(1, 2, 3);
526         final io.vavr.collection.Vector<Integer> vector = value.toVector();
527         if (value.isSingleValued()) {
528             assertThat(vector).isEqualTo(io.vavr.collection.Vector.of(1));
529         } else {
530             assertThat(vector).isEqualTo(io.vavr.collection.Vector.of(1, 2, 3));
531         }
532     }
533 
534     @Test
535     public void shouldConvertToJavaArray() {
536         final Value<Integer> value = of(1, 2, 3);
537         final Object[] ints = value.toJavaArray();
538         if (value.isSingleValued()) {
539             assertThat(ints).isEqualTo(new int[] { 1 });
540         } else {
541             assertThat(ints).isEqualTo(new int[] { 1, 2, 3 });
542         }
543     }
544 
545     @Test
546     public void shouldConvertToJavaArrayWithTypeHint() {
547         final Value<Integer> value = of(1, 2, 3);
548         final Integer[] ints = value.toJavaArray(Integer.class);
549         if (value.isSingleValued()) {
550             assertThat(ints).containsOnly(1);
551         } else {
552             assertThat(ints).containsOnly(1, 2, 3);
553         }
554     }
555 
556     @Test
557     public void shouldConvertToJavaArrayWithTypeHintPrimitiveBoolean() {
558         final Value<Boolean> value = of(true, false);
559         final Boolean[] array = value.toJavaArray(boolean.class);
560         if (value.isSingleValued()) {
561             assertThat(array).containsOnly(true);
562         } else {
563             assertThat(array).containsOnly(true, false);
564         }
565     }
566 
567     @Test
568     public void shouldConvertToJavaArrayWithTypeHintPrimitiveByte() {
569         final Value<Byte> value = of((byte) 1, (byte) 2);
570         final Byte[] array = value.toJavaArray(byte.class);
571         if (value.isSingleValued()) {
572             assertThat(array).containsOnly((byte) 1);
573         } else {
574             assertThat(array).containsOnly((byte) 1, (byte) 2);
575         }
576     }
577 
578     @Test
579     public void shouldConvertToJavaArrayWithTypeHintPrimitiveChar() {
580         final Value<Character> value = of('a', 'b');
581         final Character[] array = value.toJavaArray(char.class);
582         if (value.isSingleValued()) {
583             assertThat(array).containsOnly('a');
584         } else {
585             assertThat(array).containsOnly('a', 'b');
586         }
587     }
588 
589     @Test
590     public void shouldConvertToJavaArrayWithTypeHintPrimitiveDouble() {
591         final Value<Double> value = of(.1, .2);
592         final Double[] array = value.toJavaArray(double.class);
593         if (value.isSingleValued()) {
594             assertThat(array).containsOnly(.1);
595         } else {
596             assertThat(array).containsOnly(.1, .2);
597         }
598     }
599 
600     @Test
601     public void shouldConvertToJavaArrayWithTypeHintPrimitiveFloat() {
602         final Value<Float> value = of(.1f, .2f);
603         final Float[] array = value.toJavaArray(float.class);
604         if (value.isSingleValued()) {
605             assertThat(array).containsOnly(.1f);
606         } else {
607             assertThat(array).containsOnly(.1f, .2f);
608         }
609     }
610 
611     @Test
612     public void shouldConvertToJavaArrayWithTypeHintPrimitiveInt() {
613         final Value<Integer> value = of(1, 2);
614         final Integer[] array = value.toJavaArray(int.class);
615         if (value.isSingleValued()) {
616             assertThat(array).containsOnly(1);
617         } else {
618             assertThat(array).containsOnly(1, 2);
619         }
620     }
621 
622     @Test
623     public void shouldConvertToJavaArrayWithTypeHintPrimitiveLong() {
624         final Value<Long> value = of(1L, 2L);
625         final Long[] array = value.toJavaArray(long.class);
626         if (value.isSingleValued()) {
627             assertThat(array).containsOnly(1L);
628         } else {
629             assertThat(array).containsOnly(1L, 2L);
630         }
631     }
632 
633     @Test
634     public void shouldConvertToJavaArrayWithTypeHintPrimitiveShort() {
635         final Value<Short> value = of((short) 1, (short) 2);
636         final Short[] array = value.toJavaArray(short.class);
637         if (value.isSingleValued()) {
638             assertThat(array).containsOnly((short) 1);
639         } else {
640             assertThat(array).containsOnly((short) 1, (short) 2);
641         }
642     }
643 
644     @Test
645     public void shouldConvertToJavaArrayWithTypeHintPrimitiveVoid() {
646         final Value<Void> value = of((Void) null);
647         final Void[] array = value.toJavaArray(void.class);
648         assertThat(array).containsOnly((Void) null);
649     }
650 
651     @Test
652     public void shouldConvertToJavaCollectionUsingSupplier() {
653         final Value<Integer> value = of(1, 2, 3);
654         final java.util.List<Integer> ints = value.toJavaCollection(ArrayList::new);
655         if (value.isSingleValued()) {
656             assertThat(ints).isEqualTo(Collections.singletonList(1));
657         } else {
658             assertThat(ints).isEqualTo(Arrays.asList(1, 2, 3));
659         }
660     }
661 
662     @Test
663     public void shouldConvertToJavaList() {
664         final Value<Integer> value = of(1, 2, 3);
665         final java.util.List<Integer> list = value.toJavaList();
666         if (value.isSingleValued()) {
667             assertThat(list).isEqualTo(Collections.singletonList(1));
668         } else {
669             assertThat(list).isEqualTo(Arrays.asList(1, 2, 3));
670         }
671     }
672 
673     @Test
674     public void shouldConvertToJavaListUsingSupplier() {
675         final Value<Integer> value = of(1, 2, 3);
676         final java.util.List<Integer> ints = value.toJavaList(ArrayList::new);
677         if (value.isSingleValued()) {
678             assertThat(ints).isEqualTo(Collections.singletonList(1));
679         } else {
680             assertThat(ints).isEqualTo(Arrays.asList(1, 2, 3));
681         }
682     }
683 
684     @Test
685     public void shouldConvertToJavaMapUsingFunction() {
686         final Value<Integer> value = of(1, 2, 3);
687         final java.util.Map<Integer, Integer> map = value.toJavaMap(v -> Tuple.of(v, v));
688         if (value.isSingleValued()) {
689             assertThat(map).isEqualTo(JavaCollections.javaMap(1, 1));
690         } else {
691             assertThat(map).isEqualTo(JavaCollections.javaMap(1, 1, 2, 2, 3, 3));
692         }
693     }
694 
695     @Test
696     public void shouldConvertToJavaMapUsingSupplierAndFunction() {
697         final Value<Integer> value = of(1, 2, 3);
698         final java.util.Map<Integer, Integer> map = value.toJavaMap(java.util.HashMap::new, i -> Tuple.of(i, i));
699         if (value.isSingleValued()) {
700             assertThat(map).isEqualTo(JavaCollections.javaMap(1, 1));
701         } else {
702             assertThat(map).isEqualTo(JavaCollections.javaMap(1, 1, 2, 2, 3, 3));
703         }
704     }
705 
706     @Test
707     public void shouldConvertToJavaMapUsingSupplierAndTwoFunction() {
708         final Value<Integer> value = of(1, 2, 3);
709         final java.util.Map<Integer, String> map = value.toJavaMap(java.util.HashMap::new, Function.identity(), String::valueOf);
710         if (value.isSingleValued()) {
711             assertThat(map).isEqualTo(JavaCollections.javaMap(1, "1"));
712         } else {
713             assertThat(map).isEqualTo(JavaCollections.javaMap(1, "1", 2, "2", 3, "3"));
714         }
715     }
716 
717     @Test
718     public void shouldConvertToJavaOptional() {
719         assertThat(of(1, 2, 3).toJavaOptional()).isEqualTo(Optional.of(1));
720     }
721 
722     @Test
723     public void shouldConvertToJavaSet() {
724         final Value<Integer> value = of(1, 2, 3);
725         final java.util.Set<Integer> set = value.toJavaSet();
726         if (value.isSingleValued()) {
727             assertThat(set).isEqualTo(JavaCollections.javaSet(1));
728         } else {
729             assertThat(set).isEqualTo(JavaCollections.javaSet(1, 2, 3));
730         }
731     }
732 
733     @Test
734     public void shouldConvertToJavaSetUsingSupplier() {
735         final Value<Integer> value = of(1, 2, 3);
736         final java.util.Set<Integer> set = value.toJavaSet(java.util.HashSet::new);
737         if (value.isSingleValued()) {
738             assertThat(set).isEqualTo(JavaCollections.javaSet(1));
739         } else {
740             assertThat(set).isEqualTo(JavaCollections.javaSet(1, 2, 3));
741         }
742     }
743 
744     @Test
745     public void shouldConvertToJavaStream() {
746         final Value<Integer> value = of(1, 2, 3);
747         final java.util.stream.Stream<Integer> s1 = value.toJavaStream();
748         //noinspection Duplicates
749         if (value.isSingleValued()) {
750             final java.util.stream.Stream<Integer> s2 = java.util.stream.Stream.of(1);
751             assertThat(io.vavr.collection.List.ofAll(s1::iterator)).isEqualTo(io.vavr.collection.List.ofAll(s2::iterator));
752         } else {
753             final java.util.stream.Stream<Integer> s2 = java.util.stream.Stream.of(1, 2, 3);
754             assertThat(io.vavr.collection.List.ofAll(s1::iterator)).isEqualTo(io.vavr.collection.List.ofAll(s2::iterator));
755         }
756     }
757 
758     @Test
759     public void shouldConvertToJavaParallelStream() {
760         final Value<Integer> value = of(1, 2, 3);
761         final java.util.stream.Stream<Integer> s1 = value.toJavaParallelStream();
762         assertThat(s1.isParallel()).isTrue();
763         //noinspection Duplicates
764         if (value.isSingleValued()) {
765             final java.util.stream.Stream<Integer> s2 = java.util.stream.Stream.of(1);
766             assertThat(io.vavr.collection.List.ofAll(s1::iterator)).isEqualTo(io.vavr.collection.List.ofAll(s2::iterator));
767         } else {
768             final java.util.stream.Stream<Integer> s2 = java.util.stream.Stream.of(1, 2, 3);
769             assertThat(io.vavr.collection.List.ofAll(s1::iterator)).isEqualTo(io.vavr.collection.List.ofAll(s2::iterator));
770         }
771     }
772 
773     // toLeft / toRight
774 
775     @Test
776     public void shouldConvertToEitherLeftFromValueSupplier() {
777         final Either<Integer, String> either = of(0).toLeft(() -> "fallback");
778         assertThat(either.isLeft()).isTrue();
779         assertThat(either.getLeft()).isEqualTo(0);
780 
781         final Either<Object, String> either2 = empty().toLeft(() -> "fallback");
782         assertThat(either2.isRight()).isTrue();
783         assertThat(either2.get()).isEqualTo("fallback");
784     }
785 
786     @Test
787     public void shouldConvertToEitherLeftFromValue() {
788         final Either<Integer, String> either = of(0).toLeft("fallback");
789         assertThat(either.isLeft()).isTrue();
790         assertThat(either.getLeft()).isEqualTo(0);
791 
792         final Either<Object, String> either2 = empty().toLeft("fallback");
793         assertThat(either2.isRight()).isTrue();
794         assertThat(either2.get()).isEqualTo("fallback");
795     }
796 
797     @Test
798     public void shouldConvertToEitherRightFromValueSupplier() {
799         final Either<String, Integer> either = of(0).toRight(() -> "fallback");
800         assertThat(either.isRight()).isTrue();
801         assertThat(either.get()).isEqualTo(0);
802 
803         final Either<String, Object> either2 = empty().toRight(() -> "fallback");
804         assertThat(either2.isLeft()).isTrue();
805         assertThat(either2.getLeft()).isEqualTo("fallback");
806     }
807 
808     @Test
809     public void shouldConvertToEitherRightFromValue() {
810         final Either<String, Integer> either = of(0).toRight("fallback");
811         assertThat(either.isRight()).isTrue();
812         assertThat(either.get()).isEqualTo(0);
813 
814         final Either<String, Object> either2 = empty().toRight("fallback");
815         assertThat(either2.isLeft()).isTrue();
816         assertThat(either2.getLeft()).isEqualTo("fallback");
817     }
818 
819     // toValid / toInvalid
820 
821     @Test
822     public void shouldConvertToValidationInvalidFromValueSupplier() {
823         final Validation<Integer, String> validation = of(0).toInvalid(() -> "fallback");
824         assertThat(validation.isInvalid()).isTrue();
825         assertThat(validation.getError()).isEqualTo(0);
826 
827         final Validation<Object, String> validation2 = empty().toInvalid(() -> "fallback");
828         assertThat(validation2.isValid()).isTrue();
829         assertThat(validation2.get()).isEqualTo("fallback");
830     }
831 
832     @Test
833     public void shouldConvertToValidationInvalidFromValue() {
834         final Validation<Integer, String> validation = of(0).toInvalid("fallback");
835         assertThat(validation.isInvalid()).isTrue();
836         assertThat(validation.getError()).isEqualTo(0);
837 
838         final Validation<Object, String> validation2 = empty().toInvalid("fallback");
839         assertThat(validation2.isValid()).isTrue();
840         assertThat(validation2.get()).isEqualTo("fallback");
841     }
842 
843     @Test
844     public void shouldConvertToValidationRightFromValueSupplier() {
845         final Validation<String, Integer> validation = of(0).toValid(() -> "fallback");
846         assertThat(validation.isValid()).isTrue();
847         assertThat(validation.get()).isEqualTo(0);
848 
849         final Validation<String, Object> validation2 = empty().toValid(() -> "fallback");
850         assertThat(validation2.isInvalid()).isTrue();
851         assertThat(validation2.getError()).isEqualTo("fallback");
852     }
853 
854     @Test
855     public void shouldConvertToValidationValidFromValue() {
856         final Validation<String, Integer> validation = of(0).toValid("fallback");
857         assertThat(validation.isValid()).isTrue();
858         assertThat(validation.get()).isEqualTo(0);
859 
860         final Validation<String, Object> validation2 = empty().toValid("fallback");
861         assertThat(validation2.isInvalid()).isTrue();
862         assertThat(validation2.getError()).isEqualTo("fallback");
863     }
864 
865     // -- exists
866 
867     @Test
868     public void shouldBeAwareOfExistingElement() {
869         final Value<Integer> value = of(1, 2);
870         if (value.isSingleValued()) {
871             assertThat(value.exists(i -> i == 1)).isTrue();
872         } else {
873             assertThat(value.exists(i -> i == 2)).isTrue();
874         }
875 
876     }
877 
878     @Test
879     public void shouldBeAwareOfNonExistingElement() {
880         assertThat(this.<Integer> empty().exists(i -> i == 1)).isFalse();
881     }
882 
883     // -- forAll
884 
885     @Test
886     public void shouldBeAwareOfPropertyThatHoldsForAll() {
887         assertThat(of(2, 4).forAll(i -> i % 2 == 0)).isTrue();
888     }
889 
890     @Test
891     public void shouldBeAwareOfPropertyThatNotHoldsForAll() {
892         assertThat(of(1, 2).forAll(i -> i % 2 == 0)).isFalse();
893     }
894 
895     // ### ValueModule.Iterable ###
896 
897     // -- corresponds
898 
899     @Test
900     public void shouldntCorrespondsNilNil() {
901         assertThat(empty().corresponds(empty(), (o1, o2) -> true)).isTrue();
902     }
903 
904     @Test
905     public void shouldntCorrespondsNilNonNil() {
906         assertThat(empty().corresponds(of(1), (o1, i2) -> true)).isFalse();
907     }
908 
909     @Test
910     public void shouldntCorrespondsNonNilNil() {
911         assertThat(of(1).corresponds(empty(), (i1, o2) -> true)).isFalse();
912     }
913 
914     @Test
915     public void shouldntCorrespondsDifferentLengths() {
916         if (!empty().isSingleValued()) {
917             assertThat(of(1, 2, 3).corresponds(of(1, 2), (i1, i2) -> true)).isFalse();
918             assertThat(of(1, 2).corresponds(of(1, 2, 3), (i1, i2) -> true)).isFalse();
919         }
920     }
921 
922     @Test
923     public void shouldCorresponds() {
924         assertThat(of(1, 2, 3).corresponds(of(3, 4, 5), (i1, i2) -> i1 == i2 - 2)).isTrue();
925         assertThat(of(1, 2, 3).corresponds(of(1, 2, 3), (i1, i2) -> i1 == i2 + 1)).isFalse();
926     }
927 
928     @Test
929     public void shouldHaveAReasonableToString() {
930         final Value<Integer> value = of(1, 2);
931         value.toList(); // evaluate all elements (e.g. for Stream)
932         final String actual = value.toString();
933 
934         if (value.isSingleValued()) {
935             assertThat(actual).contains("1");
936         } else {
937             assertThat(actual).contains("1", "2");
938         }
939     }
940 
941     // -- Serialization
942 
943     /**
944      * States whether the specific Value implementation is Serializable.
945      * <p>
946      * Test classes override this method to return false if needed.
947      *
948      * @return true (by default), if the Value is Serializable, false otherwise
949      */
950     private boolean isSerializable() {
951         final Object nonEmpty = of(1);
952         if (empty() instanceof Serializable != nonEmpty instanceof Serializable) {
953             throw new Error("empty and non-empty do not consistently implement Serializable");
954         }
955         final boolean actual = nonEmpty instanceof Serializable;
956         final boolean expected = Match(nonEmpty).of(
957                 Case($(anyOf(
958                         instanceOf(Either.LeftProjection.class),
959                         instanceOf(Either.RightProjection.class),
960                         instanceOf(Future.class),
961                         instanceOf(io.vavr.collection.Iterator.class)
962                 )), false),
963                 Case($(anyOf(
964                         instanceOf(Either.class),
965                         instanceOf(Lazy.class),
966                         instanceOf(Option.class),
967                         instanceOf(Try.class),
968                         instanceOf(Traversable.class),
969                         instanceOf(Validation.class)
970                 )), true)
971         );
972         assertThat(actual).isEqualTo(expected);
973         return actual;
974     }
975 
976     @Test
977     public void shouldSerializeDeserializeEmpty() {
978         if (isSerializable()) {
979             final Value<?> testee = empty();
980             final Value<?> actual = Serializables.deserialize(Serializables.serialize(testee));
981             assertThat(actual).isEqualTo(testee);
982         }
983     }
984 
985     @Test
986     public void shouldSerializeDeserializeSingleValued() {
987         if (isSerializable()) {
988             final Value<?> testee = of(1);
989             final Value<?> actual = Serializables.deserialize(Serializables.serialize(testee));
990             assertThat(actual).isEqualTo(testee);
991         }
992     }
993 
994     @Test
995     public void shouldSerializeDeserializeMultiValued() {
996         if (isSerializable()) {
997             final Value<?> testee = of(1, 2, 3);
998             final Value<?> actual = Serializables.deserialize(Serializables.serialize(testee));
999             assertThat(actual).isEqualTo(testee);
1000         }
1001     }
1002 
1003     @Test
1004     public void shouldPreserveSingletonInstanceOnDeserialization() {
1005         if (isSerializable() && !useIsEqualToInsteadOfIsSameAs()) {
1006             final Value<?> empty = empty();
1007             final Value<?> actual = Serializables.deserialize(Serializables.serialize(empty));
1008             assertThat(actual).isSameAs(empty);
1009         }
1010     }
1011 
1012     // -- equals
1013 
1014     @Test
1015     public void shouldRecognizeSameObject() {
1016         final Value<Integer> v = of(1);
1017         //noinspection EqualsWithItself
1018         assertThat(v.equals(v)).isTrue();
1019     }
1020 
1021     @Test
1022     public void shouldRecognizeEqualObjects() {
1023         final Value<Integer> v1 = of(1);
1024         final Value<Integer> v2 = of(1);
1025         assertThat(v1.equals(v2)).isTrue();
1026     }
1027 
1028     @Test
1029     public void shouldRecognizeUnequalObjects() {
1030         final Value<Integer> v1 = of(1);
1031         final Value<Integer> v2 = of(2);
1032         assertThat(v1.equals(v2)).isFalse();
1033     }
1034 
1035 }